Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

226
Visualizações
How to make a copy of hibernate collection with cascade="all,delete-orphan"

I am trying to make a copy of a hibernate entity A like this:

A a = (A) session.get(A.class, id);
session.evict(a);
a.setId(null);
session.save(a);

This however does not work and i get the following expetion:

org.hibernate.HibernateException: Don't change the reference to a collection with cascade="all-delete-orphan": com.test.A.B

Its safe to assume this error happens because of i have a collection of B entity defined in entity A:

<list name="B"  table="B" lazy="false" cascade="all,delete-orphan">
    <key column="A_ID" not-null="true"/>
    <index column="X"/>            
    <one-to-many class="com.test.B"/>
</list>

How is it possible to make a copy of entity A, including its collection of entitys B without hibernate being unhappy about it?

over 4 years ago · Santiago Trujillo
3 Respostas
Responde à pergunta

0

If you want to copy an existing entity - modify it - and save it as new entity, then you need to deep copy that object. You can do deep copy of a object by Serializing and then De-Serializing that object.

public Object deepCopy(Object input) {

    Object output = null;
    try {
        // Writes the object
        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        ObjectOutputStream objectOutputStream = new ObjectOutputStream(byteArrayOutputStream);
        objectOutputStream.writeObject(input);

        // Reads the object
        ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(byteArrayOutputStream.toByteArray());
        ObjectInputStream objectInputStream = new ObjectInputStream(byteArrayInputStream);
        output = objectInputStream.readObject();

    } catch (Exception e) {
        e.printStackTrace();
    }
    return output;
}
over 4 years ago · Santiago Trujillo Relatório

0

I had the same problem previously in my project.

For me it works, to set the ID of the list-entries to null.

// make copy a of aOriginal by using serialisation clone 
a.setId(null);
for (B b : a.getBs()) {
    b.setId(null);
}
session.save(a);

For the clone itself I used the Apache SerializationUtils clone.

The reason is, that hibernate tries to "reuse" already persisted list-entries for the "copied" entity. But this already persisted list-entries are linked to a original entity. So it tries to "change" the list itself in the entity, because the entity changed. But you can't change the list if it is annotated with "delete-orphans" (you only can modify the entries of the list, but not the list itself). So the exception is thrown.

If I set the list-entry-IDs to null, they will also be inserted newley. And the object hierarchy (instead of only the main entity) is duplicated. So the exeption is no longer thrown.

over 4 years ago · Santiago Trujillo Relatório

0

There is no automatic way to copy objects like that. In general, the copied object could be associated with other objects which are further associated with other objects, etc, so you could end up copying a large portion of the database. Any tool you use for copying needs to be aware where in the object graph to stop copying, what not to copy (in terms of Hibernate entities those are ids, version columns and similar), and so on.

You can however utilize frameworks like Dozer to avoid most of boilerplate code you would need to write manually.

Regarding collection reassignment issue, you cannot have the same collection of B instances being assigned to two different As, as it would logically be a many-to-many association then. It is also something you would need to take care of manually, as it is specific to your business use case.

Also, make sure you don't reuse the same collection proxies from one entity instance in others, as Hibernate ties them to their original parents internally - always create a new collection in new instances (which may or may not contain the same elements).

over 4 years ago · Santiago Trujillo Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda